

if(@ARGV != 1)
{
	die("Usage: Perl DFORD.pl <Command file name>\n\n");
}

#Constructing global variables
$TOTAL_MAX_ATTEMPTS = 100;
$STORAGE_DIR = "c:\\tempSeqEx";
$factorystore = $STORAGE_DIR."\\FactoryStore.bin";
$statusfile = $STORAGE_DIR."\\reexecute.txt";
$report_path = "PexMeOp";
$nesteddepth = 0;

@allExecutedCommands = ();

open (OUTPUT, ">Timing.txt");

&executeCMDFile($ARGV[0]);

close OUTPUT;
print "DONE!!!";

###################################### BEGIN OF SUBROUTINES #######################################

#Executes a command file supplied as input
sub executeCMDFile()
{
	my($cmdfile) = @_;
	open CMDFILE, $cmdfile or die "ERROR: Could not open command file!!!\n";
	my(@allCommands) = <CMDFILE>;
	close CMDFILE;

	$ENV{"PEXME_NESTED_DEPTH"} = $nesteddepth;

	#Execute each command from the command file
	foreach(@allCommands)
	{
		my($cmd) = $_;
		chomp($cmd);	
		
		#Ignore comments in the command file
		if($cmd =~ /^\#/ || $cmd eq "")
		{
			next;
		}
		$cmd = $cmd." /ro:".$report_path;

		#Check whether the command is executed earlier due to NESTEDEXECUTE that
		#can occur from the Pex process
		my($alreadyexecuted) = 0;
		foreach(@allExecutedCommands)
		{
			my($local_loop_cmd) = $_;
			if($local_loop_cmd eq $cmd)
			{
				$alreadyexecuted = 1;
				last;
			}
		}

		if($alreadyexecuted == 1)
		{
			print "PERL: Command ".$cmd." already executed earlier. Proceeding with the next command!!!\n";
			next;
		}
		
		&executePUT($cmd);
	}
}

#Executes a PUT
sub executePUT()
{
	my($command) = @_;
	my($count) = 1;
	my($reportname) = "";

	push (@allExecutedCommands, $command);

	#Getting the report name from the commands
	if($command =~ /^(.*)(\/rn:)([^ ]+)([ ])(.*)$/)
	{
		$reportname = $3;
	}

	my($assemblyname) = "default";
	if($command =~ /^(.*)(\\)([^\\]*.dll)(.*)$/)
	{
		$assemblyname = $3;
	}	

	my($rdir) =	$report_path."\\".$reportname;
	my($maxrunswithoutnewtests) = 100;
	my($maxruns) = 200;
	my($timeout) = 120;
	my($constsolvertime) = 2;

	my($starttime) = (time)[0];


	#Delete factory suggestion store at the beginning of the PUT
	#if($nesteddepth == 0)
	#{
	#	system("D:\\PexASE\\Projects\\SeqEx\\PexMeCleaner\\bin\\Debug\\PexMeHelper.exe Clean");
	#}	

	while ($count < $TOTAL_MAX_ATTEMPTS)
	{
		#TODO: Backup test cases at every run by appending some unique ID to them

		#Delete the reports folder if exists
		#system("rmdir /Q /S ".$rdir);

		my($localcommand) = $command." /MaxRuns:".$maxruns." /MaxRunsWithoutNewTests:".$maxrunswithoutnewtests." /Timeout:".$timeout." /MaxConstraintSolverTime:".$constsolvertime;
		system($localcommand);
	 
        if(!(-e $statusfile))
		{
			#If the status file is missing
			print "Status file missing, continuinig with next PUT";
			last;
		}

		#Check whether re-execution is required.
		open FILE, $statusfile or die "Couldn't status file\n";
		binmode FILE;
		my(@statusarr) = <FILE>;
		close FILE;
	
		my($statusstr) = @statusarr[0];
		chomp($statusstr);

		if($statusstr =~ /NESTEDEXECUTE/)
		{
			print "Requested NESTEDEXECUTE from the Pex process\n";
			print "*********************************************** Restarting with new process\n\n";
			$nesteddepth++;
			$ENV{"PEXME_NESTED_DEPTH"} = $nesteddepth;
			chomp(@statusarr[1]);
			&executeCMDFile(@statusarr[1]);
			$nesteddepth--;
			$ENV{"PEXME_NESTED_DEPTH"} = $nesteddepth;
		}

		if($statusstr =~ /STOP/)
		{
			print "Requested STOP from the Pex process\n";
			last;
		}

		if($statusstr =~ /REEXECUTE/)
		{
			print "Received REEXECUTE command. So, relauching the Pex process\n";
		}

		$count++;
		$maxrunswithoutnewtests = $maxrunswithoutnewtests + 500;
		$maxruns = $maxruns + 1000;
		$timeout = $timeout + 120;
		$constsolvertime = $constsolvertime + 2;

		#delete the status file for the next run
		if(-e $statusfile)
		{
			system(" del ".$statusfile);
		}
	}

	my($endtime) = (time)[0];
	print OUTPUT "Elapsed time for ".$command.":  ".($endtime - $starttime)."seconds \n";
	&copyDir($rdir, $STORAGE_DIR."\\".$assemblyname."\\".$reportname);
}

#Subroutine for copying a directory into another
sub copyDir()
{
	my($src, $dest) = @_;
	system("mkdir ".$dest);
	my($cmd) = "robocopy /MOV /E ".$src." ".$dest;
	system($cmd);	
}